package org.teamswift.crow.rbac.controller;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.teamswift.crow.rbac.annotation.LoginRequiredOnly;
import org.teamswift.crow.rbac.annotation.PermissionAction;
import org.teamswift.crow.rbac.common.CrowDestructibleController;
import org.teamswift.crow.rbac.dto.CrowAuthorizeDto;
import org.teamswift.crow.rbac.dto.CrowRoleDto;
import org.teamswift.crow.rbac.entity.CrowPermissionResource;
import org.teamswift.crow.rbac.entity.CrowRole;
import org.teamswift.crow.rbac.service.CrowPermissionResourceService;
import org.teamswift.crow.rbac.service.CrowRoleService;
import org.teamswift.crow.rbac.vo.CrowRoleVo;
import org.teamswift.crow.rest.exception.CrowErrorMessage;
import org.teamswift.crow.rest.exception.impl.DataNotFoundException;
import org.teamswift.crow.rest.provider.jpa.CrowControllerJpa;
import org.teamswift.crow.rest.result.CrowResult;
import org.teamswift.crow.rest.result.ICrowResult;
import org.teamswift.crow.rest.utils.CrowMessageUtil;
import org.teamswift.crow.rest.utils.DozerUtils;

import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/crow/rbac/role")
public class CrowRoleController extends CrowDestructibleController<
        Integer, CrowRole, CrowRoleVo, CrowRoleDto
        > {

    private final CrowRoleService crowRoleService;

    private final CrowPermissionResourceService crowPermissionResourceService;

    public CrowRoleController(CrowRoleService crowRoleService, CrowPermissionResourceService crowPermissionResourceService) {
        this.crowRoleService = crowRoleService;
        this.crowPermissionResourceService = crowPermissionResourceService;
    }

    @PermissionAction("AUTHORIZE")
    @RequestMapping(value = "/authorize/{id}", method = RequestMethod.PUT)
    public void authorize(@PathVariable Integer id, @RequestBody @Validated List<CrowAuthorizeDto> dto) {
        CrowRole role = crowRoleService.findOneById(id);

        if(role == null) {
            throw new DataNotFoundException(
                    CrowMessageUtil.error(
                            CrowErrorMessage.NotFoundByID
                    )
            );
        }

        crowRoleService.authorize(role, dto);
    }

    @Override
    @RequestMapping(method = RequestMethod.GET, value = "/{id}")
    public ICrowResult<CrowRoleVo> findOneById(@PathVariable Integer id) {
        CrowRole role = crowRoleService.findOneById(id);
        return CrowResult.ofSuccess(
                DozerUtils.map(role, CrowRoleVo.class)
        );
    }

    @LoginRequiredOnly
    @RequestMapping(value = "/permissionResources")
    public ICrowResult<Set<CrowPermissionResource>> permissions() {
        return CrowResult.ofSuccess(crowPermissionResourceService.getAllNodes());
    }

}
